package com.flyan.game.motafx.core.ds;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;

import java.util.Iterator;

/**
 * 双向链表
 *
 * @author flyan
 * @version 1.0
 * @email flyan_by_chenu@sina.com
 * @since 2025/2/7
 */
public class DLinkedList<E> implements Iterable<E> {

    /**
     * 表头
     */
    private Node<E> head;

    /**
     * 表尾巴
     */
    private Node<E> tail;

    private int size;

    public DLinkedList() {  }

    public void addLast(E data) {
        Node<E> n = new Node<>(data);
        if (isEmpty()) {
            head = tail = n;
        } else {
            tail.next = n;
            n.prev = tail;
            tail = n;
        }
        size += 1;
    }

    public void removeFirst() {
        if (isEmpty()) {
            return;
        }
        var newHead = head.next;
        newHead.prev = null;
        head = newHead;
        size -= 1;
    }

    public void removeLast() {
        if (isEmpty()) {
            return;
        }
        tail.prev.next = null;
        size -= 1;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    @NotNull
    @Override
    public Iterator<E> iterator() {
        return new DLinkedListIterator();
    }

    private class DLinkedListIterator implements Iterator<E> {

        private Node<E> curr = head;

        @Override
        public boolean hasNext() {
            return curr != null;
        }

        @Override
        public E next() {
            var data = curr.data;
            curr = curr.next;
            return data;
        }

    }

    /**
     * 链表节点
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Node<E> {

        private E data;

        private Node<E> prev;

        private Node<E> next;

        public Node(E data) {
            this.data = data;
        }

    }

}
